package com.fzu.geometa.metadata.controller.interceptor;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fzu.geometa.common.model.UserToken;
import com.fzu.geometa.metadata.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Date;

@Component
public class LoginTokenInterceptor implements HandlerInterceptor {

    String TOKEN_PREFIX = "Bearer"; // Token前缀
    String HEADER_STRING = "Authorization"; // 存放Token 的 Header Key

    @Autowired
    HostHolder hostHolder;

    ObjectMapper objectMapper;

    @PostConstruct
    private void init() {
        objectMapper = new ObjectMapper();
        // 忽略未知 json 中的未知属性
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //  取出请求头
        // token 定义在 Authorization 中且添加了 Bearer 前缀
        String authHeader = request.getHeader(HEADER_STRING);
        if (authHeader != null && authHeader.startsWith(TOKEN_PREFIX )) {
            // 取出 token
            final String authToken = authHeader.substring(TOKEN_PREFIX.length());
            // 拆分 JWT 获取有效载荷部分
            String[] jwtParts = authToken.split("\\.");
            String encodedPayload = jwtParts[1];

            // Base64 解码有效载荷
            byte[] payloadBytes = Base64.getUrlDecoder().decode(encodedPayload);
            String payloadJson = new String(payloadBytes, StandardCharsets.UTF_8);

            // 使用 Jackson 反序列化有效载荷到实体类
            UserToken userToken = objectMapper.readValue(payloadJson, UserToken.class);

            hostHolder.setUser(userToken);
        }
        return true;
    }
}
